package edu.qqcui.study.config;

import edu.qqcui.study.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * Bean生命周期配置类
 * bean的生命周期：
 * 		bean创建---初始化----销毁的过程
 * 容器管理bean的生命周期；
 * 我们可以自定义初始化和销毁方法；容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 * 构造（对象创建）
 *      单实例：在容器启动的时候创建对象；
 *      多实例：在每次获取的时候创建对象；
 * BeanPostProcessor.postProcessBeforeInitialization
 * 初始化：
 *      对象创建完成，并赋值好，调用初始化方法。。。
 * BeanPostProcessor.postProcessAfterInitialization
 * 销毁：
 *      单实例：在容器关闭的时候进行销毁
 *      多实例：容器不会管理这个Bean，容器不会调用销毁方法
 *
 * 遍历得到容器中所有的BeanPostProcessor；挨个执行beforeInitialization，
 * 一但返回null，跳出for循环，不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
 *
 * BeanPostProcessor原理
 * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
 * initializeBean
 * {
 * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
 * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *}
 *
 * 1）指定初始化和销毁方法
 *      通过@Bean指定initMethod和destroyMethod方法
 *
 * 2)通过让Bean实现InitializingBean接口来实现初始化方法；
 *            实现DisposableBean接口来实现销毁方法
 *
 * 3）使用JSR250规范定义的两个注解来实现
 *      @PostConstruct : 在Bean创建完成并对属性赋值完成后，调用初始化方法
 *      @PreDestroy : 在容器销毁Bean之前通知我们进行清理工作
 *
 * 4）BeanPostProcessor[interface] : Bean的后置处理器，在Bean初始化前后进行一些工作
 *      postProcessBeforeInitialization ： 在初始化之前处理
 *      postProcessAfterInitialization ： 在初始化之后处理
 *
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021-06-26 15:14
 **/
@Configuration
@ComponentScan("edu.qqcui.study.bean")
public class MainConfigForLifeCycle {

	/**
	 *
	 * @return Car 实例
	 */
//	@Scope("prototype")
	@Bean(initMethod = "init", destroyMethod = "destroy")
	public Car car() {
		return new Car();
	}
}
